package com.cmc6.common.util.otherplatforms;

import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.cmc6.common.constant.BaseConstant;
import com.cmc6.common.model.vo.WxGetOpenIdVO;
import com.cmc6.common.model.vo.WxGetPhoneNumberVO;
import com.cmc6.common.model.vo.WxTokenVO;
import com.cmc6.common.properties.WxAppProperties;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;

@Component
public class WxAppUtil {

    private static RedisTemplate<String, String> redisTemplate;

    @Resource
    private void setRedisTemplate(RedisTemplate<String, String> val) {
        WxAppUtil.redisTemplate = val;
    }

    private static WxAppProperties wxAppProperties;

    @Resource
    private void setWxAppProperties(WxAppProperties val) {
        WxAppUtil.wxAppProperties = val;
    }

    /**
     * 通过微信的 code，获取微信的 openId
     */
    public static String getOpenId(String code) {

        String jsonStr = HttpUtil.get(
            "https://api.weixin.qq.com/sns/jscode2session?appid=" + wxAppProperties.getAppid() + "&secret="
                + wxAppProperties.getSecret() + "&js_code=" + code + "&grant_type=authorization_code");

        WxGetOpenIdVO wxGetOpenIdVO = JSONUtil.toBean(jsonStr, WxGetOpenIdVO.class);

        if (wxGetOpenIdVO.getErrcode() != null && wxGetOpenIdVO.getErrcode() != 0) {
            throw new RuntimeException("微信获取 openId失败，code：【" + wxGetOpenIdVO.getErrcode() + "】");
        }

        return wxGetOpenIdVO.getOpenid();
    }

    /**
     * code换取用户手机号。 每个code只能使用一次，code的有效期为5min
     */
    public static String getPhoneNumber(String code) {

        String accessToken = getAccessToken();

        JSONObject formJson = JSONUtil.createObj().set("code", code);

        String postStr = HttpUtil
            .post("https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=" + accessToken,
                formJson.toString());

        WxGetPhoneNumberVO wxGetPhoneNumberVO = JSONUtil.toBean(postStr, WxGetPhoneNumberVO.class);

        if (wxGetPhoneNumberVO.getErrcode() != null && wxGetPhoneNumberVO.getErrcode() != 0) {
            throw new RuntimeException("微信获取 用户手机号失败，code：【" + wxGetPhoneNumberVO.getErrcode() + "】");
        }

        return wxGetPhoneNumberVO.getPhone_info().getPurePhoneNumber();

    }

    /**
     * 获取小程序全局唯一后台接口调用凭据
     */
    private static String getAccessToken() {

        String accessToken = redisTemplate.opsForValue().get(BaseConstant.PRE_REDIS_WX_ACCESS_TOKEN_CACHE);

        if (StrUtil.isBlank(accessToken)) {

            String jsonStr = HttpUtil.get(
                "https://api.weixin.qq.com/cgi-bin/token?appid=" + wxAppProperties.getAppid() + "&secret="
                    + wxAppProperties.getSecret() + "&grant_type=client_credential");

            WxTokenVO wxTokenVO = JSONUtil.toBean(jsonStr, WxTokenVO.class);

            if (wxTokenVO.getErrcode() != null && wxTokenVO.getErrcode() != 0) {
                throw new RuntimeException("微信获取 token失败，code：【" + wxTokenVO.getErrcode() + "】");
            }

            // 存入 redis中
            redisTemplate.opsForValue().set(BaseConstant.PRE_REDIS_WX_ACCESS_TOKEN_CACHE, wxTokenVO.getAccess_token(),
                wxTokenVO.getExpires_in(), TimeUnit.SECONDS);

            accessToken = wxTokenVO.getAccess_token();
        }

        return accessToken;

    }

}
